package org.javaqq.face.main.base;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.event.PopupMenuListener;

import org.javaqq.face.main.RegisterWindow;
import org.javaqq.face.main.conn.ConnectionManger;
import org.javaqq.face.main.inter.ExportWindowInter;
import org.javaqq.face.main.lookandfeel.JavaQQPopupMenuUI;
import org.javaqq.face.main.tray.JavaQQTray;
import org.javaqq.face.resources.Info;
import org.javaqq.face.resources.ResourcesManager;
import org.javaqq.face.util.ImageUtils;
import org.javaqq.face.util.OSUtils;
import org.jivesoftware.smack.packet.Presence;

/**
 * The <tt>TrayMenu</tt> is the menu that appears when the user right-click
 * on the Systray icon.
 *
 * @author Nicolas Chamouard
 * @author Lubomir Marinov
 * @author Yana Stamcheva
 */
public final class TrayMenuFactory
{
    /**
     * Handles the <tt>ActionEvent</tt> when one of the menu items is selected.
     *
     * @param evt the event containing the menu item name
     */
    private static void actionPerformed(ActionEvent evt)
    {
        Object source = evt.getSource();
        String itemName;
        if (source instanceof JMenuItem)
        {
            JMenuItem menuItem = (JMenuItem) source;
            itemName = menuItem.getName();
            if(itemName.equals(Info.ONLINE_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.ONLINE_STATUS,1,Presence.Mode.available);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconOnline());
            }else if(itemName.equals(Info.QME_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.QME_STATUS,1,Presence.Mode.dnd);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconQme());
            }else if(itemName.equals(Info.AWAY_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.AWAY_STATUS,1,Presence.Mode.away);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconAway());
            }else if(itemName.equals(Info.BUSY_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.BUSY_STATUS,1,Presence.Mode.chat);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconBusy());
            }else if(itemName.equals(Info.MUTE_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.MUTE_STATUS,1,Presence.Mode.dnd);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconMute());
            }else if(itemName.equals(Info.INVISIBLE_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.INVISIBLE_STATUS,1,Presence.Mode.dnd);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconInvisible());
            }else if(itemName.equals(Info.OFFLINE_STATUS)){
            	Presence presence=new Presence(Presence.Type.available,Info.OFFLINE_STATUS,1,Presence.Mode.xa);
				ConnectionManger.getConnection().sendPacket(presence);
            	JavaQQTray.getTrayFactory().setIcon(JavaQQTray.getTrayFactory().getLogoIconOffline());
            }else if(itemName.equals("exit")){
            	ExportWindowInter win =(ExportWindowInter) RegisterWindow.getExportedWindow(ExportWindowInter.MAIN_WINDOW);
            	if(win!=null){
            		RegisterWindow.getMainFrameInstence().closeShell();
            	}else{
            		RegisterWindow.getLoginDialogInstence().closeShell();
            	}
            	System.exit(0);
            }
        }
        else
        {
            MenuItem menuItem = (MenuItem) source;
            itemName = menuItem.getName();
        }
        
    }

    /**
     * Adds the given <tt>trayMenuItem</tt> to the given <tt>trayMenu</tt>.
     * @param trayMenu the tray menu to which to add the item
     * @param trayMenuItem the item to add
     */
    private static void add(Object trayMenu, Object trayMenuItem)
    {
        if (trayMenu instanceof JPopupMenu)
            ((JPopupMenu) trayMenu).add((JMenuItem) trayMenuItem);
        else
            ((PopupMenu) trayMenu).add((MenuItem) trayMenuItem);
    }

    /**
     * Adds a <tt>PopupMenuListener</tt> to the given <tt>trayMenu</tt>.
     * @param trayMenu the tray menu to which to add a popup listener
     * @param listener the listener to add
     */
    public static void addPopupMenuListener(Object trayMenu,
        PopupMenuListener listener)
    {
        if (trayMenu instanceof JPopupMenu)
            ((JPopupMenu) trayMenu).addPopupMenuListener(listener);
    }

    /**
     * Adds a separator to the given <tt>trayMenu</tt>.
     * @param trayMenu the tray menu to which to add a separator
     */
    private static void addSeparator(Object trayMenu)
    {
        if (trayMenu instanceof JPopupMenu)
            ((JPopupMenu) trayMenu).addSeparator();
        else
            ((PopupMenu) trayMenu).addSeparator();
    }

    /**
     * Creates a tray menu for the given system tray.
     * @param tray the system tray for which we're creating a menu
     * @param swing indicates if we should create a Swing or an AWT menu
     * @return a tray menu for the given system tray
     */
    public static Object createTrayMenu(){
    	JPopupMenu trayMenu = new JPopupMenu();
    	//trayMenu.setUI(new JavaQQPopupMenuUI());
    	ActionListener listener = new ActionListener()
        {
            public void actionPerformed(ActionEvent event)
            {
                TrayMenuFactory.actionPerformed(event);
            }
        };
        add(trayMenu, createTrayMenuItem(Info.ONLINE_STATUS, Info.JAVAQQ_LANGUAGE_MENU_ONLINE,
        		            Info.JAVAQQ_IMAGE_MENU_IMONLINE, listener, true));
        add(trayMenu, createTrayMenuItem(Info.QME_STATUS, Info.JAVAQQ_LANGUAGE_MENU_QME,
	            Info.JAVAQQ_IMAGE_MENU_QME, listener, true));
        add(trayMenu, createTrayMenuItem(Info.AWAY_STATUS, Info.JAVAQQ_LANGUAGE_MENU_AWAY,
	            Info.JAVAQQ_IMAGE_MENU_AWAY, listener, true));
        add(trayMenu, createTrayMenuItem(Info.BUSY_STATUS, Info.JAVAQQ_LANGUAGE_MENU_BUSY,
	            Info.JAVAQQ_IMAGE_MENU_BUSY, listener, true));
        add(trayMenu, createTrayMenuItem(Info.MUTE_STATUS, Info.JAVAQQ_LANGUAGE_MENU_MUTE,
	            Info.JAVAQQ_IMAGE_MENU_MUTE, listener, true));
        add(trayMenu, createTrayMenuItem(Info.INVISIBLE_STATUS, Info.JAVAQQ_LANGUAGE_MENU_INVISIBLE,
	            Info.JAVAQQ_IMAGE_MENU_INVISIBLE, listener, true));
        add(trayMenu, createTrayMenuItem(Info.OFFLINE_STATUS, Info.JAVAQQ_LANGUAGE_MENU_IMOFFLINE,
	            Info.JAVAQQ_IMAGE_MENU_IMOFFLINE, listener, true));
        addSeparator(trayMenu);
        add(trayMenu, createTrayMenuItem("lock", Info.JAVAQQ_LANGUAGE_MENU_LOCK,
	            Info.JAVAQQ_IMAGE_MENU_LOCK, listener, true));
        addSeparator(trayMenu);
        add(trayMenu, createTrayMenuItem("open", Info.JAVAQQ_LANGUAGE_MENU_OPEN,
	             listener, true));
        addSeparator(trayMenu);
        add(trayMenu, createTrayMenuItem("exit", Info.JAVAQQ_LANGUAGE_MENU_EXIT,
	             listener, true));
        return trayMenu;
    }

    /**
     * Creates a tray menu with the given <tt>name</tt>, text given by
     * <tt>textID</tt> and icon given by <tt>iconID</tt>. The <tt>listener</tt>
     * is handling item events and the <tt>swing</tt> value indicates if we
     * should create a Swing menu item or and an AWT item.
     * @param name the name of the item
     * @param textID the identifier of the text in the localization resources
     * @param iconID the identifier of the icon in the image resources
     * @param listener the <tt>ActionListener</tt> handling action events
     * @param swing indicates if we should create a Swing menu item or an AWT
     * item
     * @return a reference to the newly created item
     */
    private static Object createTrayMenuItem(   String name,
                                                String textID,
                                                String iconID,
                                                ActionListener listener,
                                                boolean swing)
    {
        String text = ResourcesManager.getResourcesManagerFactory().getLanguageValue(textID);
        Object trayMenuItem;
        if (swing)
        {
            JMenuItem menuItem = 
                new JMenuItem(text, new ImageIcon(ImageUtils.getImage(ResourcesManager.getResourcesManagerFactory().getImageValue(iconID)))/*Resources.getImage(iconID)*/);
            menuItem.setName(name);
            menuItem.addActionListener(listener);
            trayMenuItem = menuItem;
        }
        else
        {
            MenuItem menuItem = new MenuItem(text);
            menuItem.setName(name);
            menuItem.addActionListener(listener);
            trayMenuItem = menuItem;
        }
        return trayMenuItem;
    }
    
    private static Object createTrayMenuItem(   String name,
            String textID,
            ActionListener listener,
            boolean swing)
    {
		String text = ResourcesManager.getResourcesManagerFactory().getLanguageValue(textID);
		Object trayMenuItem;
		if (swing) {
			JMenuItem menuItem = new JMenuItem(text);
			menuItem.setName(name);
			menuItem.addActionListener(listener);
			trayMenuItem = menuItem;
		} else {
			MenuItem menuItem = new MenuItem(text);
			menuItem.setName(name);
			menuItem.addActionListener(listener);
			trayMenuItem = menuItem;
		}
		return trayMenuItem;
    }

    /**
     * Changes the tray menu item properties, like name, text and icon.
     * @param trayItem the tray menu item to change
     * @param name the new name of the item
     * @param textID the new text identifier
     * @param iconID the new icon string identifier
     */
    private static void changeTrayMenuItem( Object trayItem,
                                            String name,
                                            String textID,
                                            String iconID)
    {
        String text = ResourcesManager.getResourcesManagerFactory().getLanguageValue(textID);

        if (trayItem instanceof JMenuItem)
        {
            JMenuItem jmenuItem = (JMenuItem) trayItem;
            jmenuItem.setName(name);
            jmenuItem.setText(text);
            jmenuItem.setIcon(new ImageIcon(ImageUtils.getImage(ResourcesManager.getResourcesManagerFactory().getImageValue(iconID))));
        }
        else if (trayItem instanceof MenuItem)
        {
            MenuItem menuItem = (MenuItem) trayItem;
            menuItem.setName(name);
            menuItem.setLabel(text);
        }
    }

    /**
     * Returns <tt>true</tt> if the given <tt>trayMenu</tt> is visible,
     * otherwise returns <tt>false</tt>.
     * @param trayMenu the <tt>TrayMenu</tt> to check
     * @return <tt>true</tt> if the given <tt>trayMenu</tt> is visible,
     * otherwise returns <tt>false</tt>
     */
    public static boolean isVisible(Object trayMenu)
    {
        if (trayMenu instanceof JPopupMenu)
            return ((JPopupMenu) trayMenu).isVisible();
        return false;
    }
}